package com.t.bricks.bussiness.db.dao.wechat.impl;

import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import com.t.bricks.bussiness.db.dao.wechat.AccessTokenDao;
import com.t.bricks.bussiness.model.agent.AgentInfo;
import com.t.bricks.model.Log;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.utils.function.data.IntegerUtil;
import com.t.bricks.utils.function.json.JacksonShell;
import com.t.bricks.utils.function.url.HttpsUtil;
import com.t.bricks.utils.function.url.URLUtil;

/**
 * 微信AccessToken值的处理
 */
@Repository
public class AccessTokenDaoImpl implements AccessTokenDao {

	/**
	 * 公众号的appid,同时设置在微信平台
	 */
	@Value("${wechat.appid:去微信平台设置}")
	private String appid;
	
	/**
	 * 公众号的appsecret同时设置在微信平台
	 */
	@Value("${wechat.appsecret:去微信平台设置}")
	private String appsecret;
	
	/**
	 * 请求微信token值的代理服务地址
	 * 警告:如果本程序部署在'微信白名单'时不需要设置;如果本程序部署内网则需要将'微信白名单'中的公网服务器A做代理转发,同时代理转发程序要部署到其公网服务器A
	 */
	@Value("${wechat.token.agent.url:未设置}")
	private String tokenAgentUrl;

	/**
	 * 最后请求时间
	 */
	private long lAccessLastTime = 0;
	
	/**
	 * 保存的AccessToken
	 */
	private String sAccessToken = null;
	
	/**
	 * 取Token
	 * @return
	 */
	@Override
	public synchronized MsgEmity getToken() {
		long newTime = System.currentTimeMillis();
		if (lAccessLastTime != 0 && (newTime - lAccessLastTime) < 5400000) {// 1.5 * 60 * 60 * 1000 = 5400000
			return new MsgEmity(true, "获取成功", sAccessToken);
		}
		
		//获取access_token接口地址,来自腾讯
		String url = String.format(
				"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
				appid,
				appsecret);

		MsgEmity me = null;
		if ("未设置".equals(tokenAgentUrl) || "".equals(tokenAgentUrl)) {
			me = HttpsUtil.post(url, null);//发起get请求获取凭证
		} else {
			me = agentToken(url);
		}
		
		if (!me.isSuccess()) {
			return me;
		}
		
		String httpStr = me.getData();
		Map<String, String> map = JacksonShell.toJavaObject(httpStr, Map.class);
		
		lAccessLastTime = 0;
		sAccessToken = null;
		
		if (map == null) {
			return MsgEmity.err(7001, "获取accessToken失败");
		}
		
		int iCode = 0;
		try {
			if (!map.containsKey("access_token")) {
				iCode = IntegerUtil.strToInt(map.get("errcode"), -1);
				if (iCode != 0) {
					Log.error("获取token失败,错误码:", iCode, ";错误信息:", map.get("errmsg"));
					return MsgEmity.err(7002, "获取accessToken失败,错误码:", String.valueOf(iCode), ";错误信息:", map.get("errmsg"));
				}
				
				return MsgEmity.err(7003, "获取accessToken失败,未知的格式:", httpStr);
			}
			
			sAccessToken = map.get("access_token");
		} catch (Exception e) {
			Log.error("获取token发生异常:", e.getMessage());
		}
		
		if (null == sAccessToken || "".equals(sAccessToken.trim())) {
			return MsgEmity.err(7003, "获取accessToken不符合预期,当前值为:", sAccessToken);
		}
		
		lAccessLastTime = newTime;
	
		return new MsgEmity(true, "获取成功", sAccessToken);
	}
	
	/**
	 *
	 * @param url
	 * @return
	 */
	private MsgEmity agentToken(String url) {
		if ("未设置".equals(tokenAgentUrl) || "".equals(tokenAgentUrl)) {
			return MsgEmity.err(6001, "未设置转发代理");
		}
		
		AgentInfo agentInfo = new AgentInfo(url, "POST", null);
		String json = JacksonShell.toJSONString(agentInfo);
		MsgEmity me = URLUtil.postJson(tokenAgentUrl, json);
		if (!me.isSuccess()) {
			return MsgEmity.err(6002, "通过代理转发操作执行失败:", me.getMsg(), "对方码值:", me.getData());
		}
		
		me = JacksonShell.toJavaObject(me.getData(), MsgEmity.class);
		
		return me;
	}

}
